﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Simple Image Statistics Threshold (SIS)
    /// </summary>
    public class SISThreshold : BaseForeBackgroundColorFilter
    {
        protected byte m_bThreshold = 0;

        /// <summary>
        /// default constructor
        /// </summary>
        public SISThreshold()
        {
        }

        /// <summary>
        /// constructor to apply Threshold
        /// </summary>
        /// <param name="_bThreshold"></param>
        public SISThreshold(byte _bThreshold)
        {
            m_bThreshold = _bThreshold;
        }

        /// <summary>
        /// used to clone this instance
        /// </summary>
        /// <param name="_sisThreshold"></param>
        internal SISThreshold(SISThreshold _sisThreshold)
        {
            m_bThreshold = _sisThreshold.m_bThreshold;
        }

        /// <summary>
        /// Gets or sets threshold for this filter...
        /// </summary>
        public byte Threshold
        {
            get { return m_bThreshold; }
            set { m_bThreshold = value; }
        }

        /// <summary>
        /// Executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;
            int x = 0;
            int y = 0;

            int nI = 0;
            double ex = 0;
            double ey = 0;
            double nWeight = 0;
            double nTotalWeight = 0;
            double nTotal = 0;
            for (y = 1; y < nHeight - 1; y++)
            {
                for (x = 1; x < nWidth - 1; x++)
                {
                    ex = _bitmap.GetGrayPixelValue(x + 1, y) - _bitmap.GetGrayPixelValue(x - 1, y);
                    ey = _bitmap.GetGrayPixelValue(x, y + 1) - _bitmap.GetGrayPixelValue(x, y - 1);
                    nWeight = Math.Max(ex, ey);
                    nTotalWeight += nWeight;
                    nTotal += nWeight * _bitmap.GetGrayPixelValue(x, y);
                }
            }

            byte bGlobalThreshold = (nTotalWeight == 0) ? (byte)0 : (byte)(nTotal / nTotalWeight);
            byte bAbsoluteThreshold = (byte)(bGlobalThreshold + m_bThreshold);
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    _bitmap.SetPixel(x, y, _bitmap.GetGrayPixelValue(x, y) > bAbsoluteThreshold ? m_ColorForeground : m_ColorBackground);
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// Clones this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new SISThreshold(this);
        }
    }
}
